﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.Remoting.Messaging;

namespace AsyncDelegateForm
{
    public delegate string DoWork();
    public delegate void SetValueDelegate(Label tb, string value);

    public partial class Form1 : Form
    {
        private BackgroundWorker backWorker = new BackgroundWorker();
        public Form1()
        {
            InitializeComponent();
            InitBackGroundWorker();
        }

        private void InitBackGroundWorker()
        {
            backWorker.DoWork += new DoWorkEventHandler(backWorker_DoWork);
            backWorker.ProgressChanged += new ProgressChangedEventHandler(backWorker_ProgressChanged);
            backWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backWorker_RunWorkerCompleted);
        }

        void backWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.label1.Text = e.Result.ToString();
        }

        void backWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.label1.Text = string.Format("当前已经完成了{0}%",e.ProgressPercentage);
        }

        void backWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            e.Result = this.GetSomething();
        }

        private string GetSomething()
        {
            Thread.Sleep(3000);
            string temp= DateTime.Now.ToString();
            return temp;
        }

        private string GetValidation()
        {
            string temp= DateTime.Now.ToString();
            return temp;
        }

        private void GetSomethingCompleted(IAsyncResult result)
        {
            GetValidation();
            DoWork dw = (DoWork)((AsyncResult)result).AsyncDelegate;
            string a = string.Empty;
            a= dw.EndInvoke(result);

            //方式1.直接在非UI线程中访问UI线程中创建的控件是不被许可的
            //this.label1.Text = a;

            //方式2.调用控件的BeginInvoke方法，可以跨线程访问对象
            this.BeginInvoke(new SetValueDelegate(SetVaule),this.label1,a);
        }

        
        private void SetVaule(Label lable, string value)
        {
            lable.Text = value;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string temp = string.Empty;
            this.label1.Text= GetSomething();
        }

        private void button2_Click(object sender, EventArgs e)
        {
           this.label2.Text= GetValidation();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            DoWork dw = new DoWork(GetSomething);
            AsyncCallback callBack = new AsyncCallback(GetSomethingCompleted);
            string temp = string.Empty;
            dw.BeginInvoke(callBack,"");
        }

        private void button3_Click(object sender, EventArgs e)
        {
            this.label2.Text = GetValidation();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }


        
        private void button6_Click(object sender, EventArgs e)
        {
            this.backWorker.RunWorkerAsync();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            this.label2.Text = DateTime.Now.ToString();
        }



    }
}
